/***************************************************************************
 *   Copyright © 2010 by Nikolay Kornaev                                   *
 *   n.kornaev@gmail.com                                                   *
 *                                                                         *
 *                    This file is part of neuma.                          *
 *                                                                         *
 *   neuma is free software; you can redistribute it and/or modify it      *
 *   under the terms of the GNU General Public License as published by     *
 *   the Free Software Foundation; either version 3 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   neuma is distributed in the hope that it will be useful,              *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, see <http://www.gnu.org/licenses/>   *
 ***************************************************************************/

#include <QtGlobal>
#include <QtCore>
#include <QtGui>

#include "constants.h"
#include "Interface_SourceParser.h"
#include "MainWindow.h"

namespace Neuma
{
  void MainWindow::on_aNew_triggered()
  {
    if (maybeSave())
    {
      teSource->clear();
      QStringList availableTypes = plugins.keys();
      SourceParser *sp = currentSP;
      if (availableTypes.size() > 1)
      {
        /// TODO: диалог выбора типа исходника, установка sp
        // sp = .....
      }
      teSource->setPlainText(sp->defaultContent());
      on_aRefresh_triggered();
      setCurrentFile("");
    }
  }

  void MainWindow::on_aOpen_triggered()
  {
    if (maybeSave())
    {
      QString fileName = QFileDialog::getOpenFileName(this, tr("Открыть файл"), path,
          constructFilter(false));
      if (!fileName.isEmpty())
        loadFile(fileName);
    }
  }

  bool MainWindow::on_aSave_triggered()
  {
    if (curFile.isEmpty())
      return on_aSaveAs_triggered();
    else return saveFile(curFile);
  }

  bool MainWindow::on_aSaveAs_triggered()
  {
    QString fileName = QFileDialog::getSaveFileName(this, tr("Сохранить файл"), path,
        constructFilter(true)); /// пока что представим, что конвертация невозможна
    if (fileName.isEmpty())
      return false;

    return saveFile(fileName);
  }

  void MainWindow::loadFile(const QString &fileName)
  {
    QFile file(fileName);
    if (!file.open(QFile::ReadOnly | QFile::Text))
    {
      QMessageBox::warning(this, N_APP_NAME,
          tr("Невозможно прочитать файл %1:\n%2.") .arg(fileName) .arg(file.errorString()));
      debug(QString("Can't load file \"%1\". Error: \"%2\"") .arg(fileName) .arg(file.errorString()),
          QtWarningMsg);
      emptyLoad();
      return;
    }

    QString ext = QFileInfo(file).suffix();
    SourceParser *sp = plugins.value(ext);
    if (!sp)
    {
      QMessageBox::warning(this, N_APP_NAME, tr(
          "Невозможно найти подходящий плагин для открытия файла %1.") .arg(fileName));
      debug(QString("Can't find plugin to open file \"%1\".") .arg(fileName), QtWarningMsg);
      emptyLoad();
      return;
    }
    QApplication::setOverrideCursor(Qt::WaitCursor);
    currentSP = sp;
    debug(QString("File \"%1\" opened by \"%2\"").arg(file.fileName()).arg(sp->pluginName()));

    QTextStream in(&file);
    in.setCodec("UTF-8");
    QString text = in.readAll();
    teSource->setText(text);
    on_aRefresh_triggered();
    QApplication::restoreOverrideCursor();

    setCurrentFile(fileName);
  }

  bool MainWindow::saveFile(const QString &fileName)
  {
    QFile file(fileName);
    if (!file.open(QFile::WriteOnly | QFile::Text))
    {
      QMessageBox::warning(this, N_APP_NAME,
          tr("Невозможно записать файл %1:\n%2.") .arg(fileName) .arg(file.errorString()));
      return false;
    }

    QApplication::setOverrideCursor(Qt::WaitCursor);
    QTextStream out(&file);
    out.setCodec("UTF-8");
    QString o;
    currentSP->toText(data, o); /// пока что представим, что конвертация невозможна
    out << o;
    QApplication::restoreOverrideCursor();

    setCurrentFile(fileName);
    return true;
  }

  void MainWindow::setCurrentFile(const QString &fileName)
  {
    curFile = fileName;
    teSource->document()->setModified(false);
    setWindowModified(false);

    QString shownName = curFile;
    if (curFile.isEmpty())
      shownName = "новый файл";
    setWindowFilePath(shownName);
  }

  QString MainWindow::strippedName(const QString &fullFileName)
  {
    qDebug() << QFileInfo(fullFileName).fileName();
    return QFileInfo(fullFileName).fileName();
  }

  bool MainWindow::maybeSave()
  {
    if (teSource->document()->isModified())
    {
      QMessageBox::StandardButton ret;
      ret = QMessageBox::warning(this, N_APP_NAME, tr("Документ изменён.\n"
        "Вы хотите сохранить изменения?"), QMessageBox::Save | QMessageBox::Discard
          | QMessageBox::Cancel);
      if (ret == QMessageBox::Save)
        return on_aSave_triggered();
      else if (ret == QMessageBox::Cancel)
        return false;
    }
    return true;
  }

  void MainWindow::documentWasModified()
  {
    setWindowModified(teSource->document()->isModified());
  }

  QString MainWindow::constructFilter(bool onlyCyrrent)
  {
    QString out;
    if (onlyCyrrent)
    {
      SourceParser *sp = currentSP;
      out = QString("%1 (*.%2)").arg(sp->extensionDescription()).arg(sp->supportedExtension());
    }
    else
    {
      QStringList availableTypes = plugins.keys();
      foreach(const QString t, availableTypes)
        {
          SourceParser *sp = plugins.value(t);
          out.append(QString("%1 (*.%2);;").arg(sp->extensionDescription()).arg(
              sp->supportedExtension()));
        }
    }
    return out;
  }
}
